package Client;

import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.EOFException;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.net.Socket;

import Server.Server;
/**
 * 
 * <p>
 * Klasa odpowiadajaca za polaczenie klienta z serwerem.
 * Inicjalizuje polaczenie oraz odbiera i wysyla dane.
 * </p>
 * 
 * @author Dariusz Orlowski
 *
 */
public class ClientConnection implements Runnable{

	private int port = 4444;
	private String host = "localhost";
	private String nickname;

	private Socket connection;

	private InputStream inStream;
	private DataInputStream inDataStream;
	private OutputStream outStream;
	private DataOutputStream outDataStream;

	public ClientConnection(String nick){
		nickname=nick;
		try{
			connection = new Socket ( host , port );
		    connection.setTcpNoDelay(true);
	
		    outStream = connection.getOutputStream ();
		    outDataStream = new DataOutputStream ( outStream );
		    inStream = connection.getInputStream ();
		    inDataStream = new DataInputStream ( inStream );

		    Byte byte_type=0;
			byte[] ByteArray = nick.getBytes();
			sendToServer(byte_type,ByteArray);	//typ 0 - logowanie
		}
		catch ( IOException except)  {
			except.printStackTrace ();
	    }
		(new Thread(this)).start();
		
	}
		
	//metoda run (watek) odczytujaca wiadomosci wyslane przez serwer
	public void run(){
		byte type;
		int length;
		byte[] data;
		//odczytywanie wiadomosci
		try{
			while(true){
				if (inDataStream.available()>=5){//minimum 5 bajtow
					type=inDataStream.readByte();
					length=inDataStream.readInt();
					inDataStream.read(data = new byte[length], 0, length);
					//deserializacja + wykonywanie kodu ze wzgledu na typ przesylanej informacji
				}
				
				
				Thread.sleep(10);
			}
		}
		catch ( EOFException ex ) {ex.printStackTrace();}
		catch ( IOException ex ) {ex.printStackTrace();}
		catch(InterruptedException ex){ex.printStackTrace();}
	}

	//metoda wysylajaca wiadomosc do serwera
	private void sendToServer(byte type, byte[] data){  
		try{
			outDataStream.write(type);
			outDataStream.writeInt(data.length);
			outDataStream.write(data);
			outDataStream.flush();
		}
		catch (IOException e)
		{
			e.printStackTrace();
		}
	}

	//metoda serializujaca obiekt do tablicy bajtow
	private byte[] serializuj(Object o){
		ByteArrayOutputStream baos;
		ObjectOutputStream out;
		
		try
		{
			baos = new ByteArrayOutputStream();
			out = new ObjectOutputStream(baos);	
			out.writeObject(o);
			out.close();
			
			return baos.toByteArray();
		}
		catch (IOException e)
		{
			e.printStackTrace();
			return null;
		}
	}
	
}

	
